gh-74020: Raise ValueError for negative values converted to unsigned#121114
gh-74020: Raise ValueError for negative values converted to unsigned#121114serhiy-storchaka wants to merge 8 commits intopython:mainfrom
Conversation
…igned Converting negative Python integer to a C unsigned integer type now raises ValueError, not OverflowError. Affected C API: PyLong_AsUnsignedLong(), PyLong_AsUnsignedLongLong(), PyLong_AsSize_t() and the "b" format unit in PyArg_Parse().
skirpichev
left a comment
There was a problem hiding this comment.
I would expect this breaks a lot of people code.
Lets do this with a deprecation period.
| self.assertRaises(ValueError, (-1).to_bytes, 2, 'big', signed=False) | ||
| self.assertRaises(ValueError, (-1).to_bytes, 2, 'little', signed=False) |
There was a problem hiding this comment.
You should adjust int.to_bytes() docs (both docstring and sphinx).
BTW, I think there could be a test with a negative input and signed=True.
There was a problem hiding this comment.
Updated docs.
There is a test with a negative input and signed=True above.
There was a problem hiding this comment.
There is a test with a negative input and signed=True above.
Hmm, maybe. I don't see it.
picnixz
left a comment
There was a problem hiding this comment.
I'm really worried that now, anyone using PyLong_AsUnsignedLong would need to either change how they handle the exception or now be dealing with two different exceptions.
I'm not confident enough to actually just make this change. OverflowError fits in the sense that it's outside of the expected range, but the transition is too hard. I suggested raising DomainError which would inherit from OverflowError and ValueError but code paths with distinct handling of ValueError and OverflowError could be broken.
An easy way to make it work is to introduce a new function that would properly raise what is meant to be raised, and deprecate those functions.
So I'm not -1 as strong as @rhettinger, but I still think it's better to be continue with this, even if it's annoying on our side. We could have some private helpers that would do something like:
try:
x = asulong(X)
except OverflowError:
if X < 0:
raise ValueError
raiseOr something that can store in addition the fact that something is < 0 or not, like PyLong_AsLongAndOverflow but for ULong instead where we add also a isnegative flag:
int _PyLong_AsUnsignedLong(PyObject *long, int *overflow, int *negative);| integer must implement either :meth:`~object.__int__` or | ||
| :meth:`~object.__index__`. (Contributed by Mark Dickinson in :gh:`119743`.) | ||
|
|
||
| * Converting negative Python integer to a C unsigned integer type now raises |
There was a problem hiding this comment.
This will need to be moved to 3.15 and marked as an incompatible change.
Converting negative Python integer to a C unsigned integer type now raises ValueError, not OverflowError.
Affected C API: PyLong_AsUnsignedLong(), PyLong_AsUnsignedLongLong(), PyLong_AsSize_t() and the "b" format unit in PyArg_Parse().
📚 Documentation preview 📚: https://cpython-previews--121114.org.readthedocs.build/